#include "scenecontrol.hpp"

namespace VN{
    BackLogItem::BackLogItem(Window* w,vector<TextMod> name,const vector<TextMod> content):TextItem(w,""){
        name_t=BuildText(name,default_font->_font);
        content_t=BuildText(content,default_font->_font,info);
    }
    void BackLogItem::Draw(Renderer* render,ListState state,SDL_Rect& rect){
        auto cache=rect.w;
        SDL_QueryTexture(name_t,0,0,&rect.w,0);
        render->DrawTexture(0,&rect,name_t);
        rect.w=cache;
    }
    BackLogItem::~BackLogItem(){
        SDL_DestroyTexture(name_t);
        SDL_DestroyTexture(content_t);
    }
    LogTextItem::LogTextItem(Window* win,int w,int h,int y,SDL_Texture* c):TextItem(win,""),content_t(c),
    src({0,y,w,h}){}
    LogTextItem::~LogTextItem(){}
    void LogTextItem::Draw(Renderer* render,ListState state,SDL_Rect& rect){
        auto _w=rect.w,_h=rect.h;
        rect.w=src.w,rect.h=src.h;
        render->DrawTexture(&src,&rect,content_t);
        rect.w=_w,rect.h=_h;
    }
    void SaveName::OnTextChanged(){}
    void SaveName::OnInputFinish(){}
    SaveName::SaveName(Window* w,SDL_Rect r,const char* alert):InputBox(w,r,Color::White,
    default_font,alert){}

    void EffectBox::OnChanged(){g->MuteEffect();}
    EffectBox::EffectBox(SDL_Point p,GameScene* g):CheckBox((Window*)g->window()),g(g){
        value=true;
        _area.x=p.x,_area.y=p.y;
        auto s=default_font->height();
        _area.w=s,_area.h=s;
    }
    EffectBox::~EffectBox(){}

    void MusicBox::OnChanged(){g->MuteMusic();}
    MusicBox::MusicBox(SDL_Point p,GameScene* g):CheckBox((Window*)g->window()),g(g){
        value=true;
        _area.x=p.x,_area.y=p.y;
        auto s=default_font->height();
        _area.w=s,_area.h=s;
    }
    MusicBox::~MusicBox(){}

    void QuitButton::OnClick(int x,int y,unsigned char key){exit(0);}
    void QuitButton::OnDoubleClick(int x,int y,unsigned char key){exit(0);}
    QuitButton::QuitButton(SDL_Point p,Window* w,const char* text,SDL_Color text_color)
    :TextButton(w,p,text,text_color){}
    QuitButton::~QuitButton(){}

    void SkipButton::OnClick(int x,int y,unsigned char key){g->Skip();}
    void SkipButton::OnDoubleClick(int x,int y,unsigned char key){g->Skip();}
    SkipButton::SkipButton(SDL_Point p,GameScene* g,const char* text,SDL_Color text_color)
    :TextButton((Window*)g->window(),p,text,text_color),g(g){}
    SkipButton::~SkipButton(){}

    void EnterOptionButton::OnClick(int x,int y,unsigned char key){g->EnterOption();}
    void EnterOptionButton::OnDoubleClick(int x,int y,unsigned char key){g->EnterOption();}
    EnterOptionButton::EnterOptionButton(SDL_Point p,GameScene* g,const char* text,SDL_Color text_color)
    :TextButton((Window*)g->window(),p,text,text_color),g(g){}
    EnterOptionButton::~EnterOptionButton(){}

    void ConfirmSaveButton::OnClick(int x,int y,unsigned char key){g->ConfirmSave();}
    void ConfirmSaveButton::OnDoubleClick(int x,int y,unsigned char key){g->ConfirmSave();}
    ConfirmSaveButton::ConfirmSaveButton(SDL_Point p,GameScene* g,
    const char* text,SDL_Color text_color):TextButton((Window*)g->window(),p,text,text_color),g(g){}
    ConfirmSaveButton::~ConfirmSaveButton(){}

    void EnterSaveButton::OnClick(int x,int y,unsigned char key){g->EnterSave();}
    void EnterSaveButton::OnDoubleClick(int x,int y,unsigned char key){g->EnterSave();}
    EnterSaveButton::EnterSaveButton(SDL_Point p,GameScene* g,const char* text,SDL_Color text_color)
    :TextButton((Window*)g->window(),p,text,text_color),g(g){}
    EnterSaveButton::~EnterSaveButton(){}

    void OpenBackLogButton::OnClick(int x,int y,unsigned char key){g->OpenBackLog();}
    void OpenBackLogButton::OnDoubleClick(int x,int y,unsigned char key){g->OpenBackLog();}
    OpenBackLogButton::OpenBackLogButton(SDL_Point p,GameScene* g,const char* text,SDL_Color text_color)
    :TextButton((Window*)g->window(),p,text,text_color),g(g){}
    OpenBackLogButton::~OpenBackLogButton(){}

    void LoadSaveButton::OnClick(int x,int y,unsigned char key){g->EnterLoad();}
    void LoadSaveButton::OnDoubleClick(int x,int y,unsigned char key){g->EnterLoad();}
    LoadSaveButton::LoadSaveButton(SDL_Point p,GameScene* g,const char* text,SDL_Color text_color)
    :TextButton((Window*)g->window(),p,text,text_color),g(g){}
    LoadSaveButton::~LoadSaveButton(){}

    void AutoPlayButton::OnClick(int x,int y,unsigned char key){g->AutoPlay();}
    void AutoPlayButton::OnDoubleClick(int x,int y,unsigned char key){g->AutoPlay();}
    AutoPlayButton::AutoPlayButton(SDL_Point p,GameScene* g,
    const char* text,SDL_Color text_color):TextButton((Window*)g->window(),p,text,text_color),g(g){}
    AutoPlayButton::~AutoPlayButton(){}
    void AutoPlayButton::_draw(){
        auto r=_belong->renderer;
        if(g->IsAutoPlay()){
            r->SetColor({255,255,0,255});
            r->DrawRect(_area);
        }
        r->DrawTexture(0,&_area,_t);
    }
    void AutoPlayFastButton::OnClick(int x,int y,unsigned char key){g->SetAutoSpeed(true);}
    void AutoPlayFastButton::OnDoubleClick(int x,int y,unsigned char key){g->SetAutoSpeed(true);}
    AutoPlayFastButton::AutoPlayFastButton(SDL_Point p,GameScene* g,const char* text,SDL_Color text_color)
    :TextButton((Window*)g->window(),p,text,text_color),g(g){}
    AutoPlayFastButton::~AutoPlayFastButton(){}
    void AutoPlayFastButton::_draw(){
        auto r=_belong->renderer;
        if(g->dialog->IsFast()){
            r->SetColor({255,255,0,255});
            r->DrawRect(_area);
        }
        r->DrawTexture(0,&_area,_t);
    }

    void AutoPlayNormalButton::OnClick(int x,int y,unsigned char key){g->SetAutoSpeed(false);}
    void AutoPlayNormalButton::OnDoubleClick(int x,int y,unsigned char key){g->SetAutoSpeed(false);}
    AutoPlayNormalButton::AutoPlayNormalButton(SDL_Point p,GameScene* g,const char* text,SDL_Color text_color)
    :TextButton((Window*)g->window(),p,text,text_color),g(g){}
    AutoPlayNormalButton::~AutoPlayNormalButton(){}
    void AutoPlayNormalButton::_draw(){
        auto r=_belong->renderer;
        if(!g->dialog->IsFast()){
            r->SetColor({255,255,0,255});
            r->DrawRect(_area);
        }
        r->DrawTexture(0,&_area,_t);
    }

    void StartGameButton::OnClick(int x,int y,unsigned char key){g->StartGame();}
    void StartGameButton::OnDoubleClick(int x,int y,unsigned char key){g->StartGame();}
    StartGameButton::StartGameButton(SDL_Point p,GameScene* g,const char* text,SDL_Color text_color)
    :TextButton((Window*)g->window(),p,text,text_color),g(g){}
    StartGameButton::~StartGameButton(){}

    void EnterCGButton::OnClick(int x,int y,unsigned char key){g->EnterCG();}
    void EnterCGButton::OnDoubleClick(int x,int y,unsigned char key){g->EnterCG();}
    EnterCGButton::EnterCGButton(SDL_Point p,GameScene* g,const char* text,SDL_Color text_color)
    :TextButton((Window*)g->window(),p,text,text_color),g(g){}
    EnterCGButton::~EnterCGButton(){}

    void EnterMainButton::OnClick(int x,int y,unsigned char key){g->EnterMain();}
    void EnterMainButton::OnDoubleClick(int x,int y,unsigned char key){g->EnterMain();}
    EnterMainButton::EnterMainButton(SDL_Point p,GameScene* g,const char* text,SDL_Color text_color)
    :TextButton((Window*)g->window(),p,text,text_color),g(g){}
    EnterMainButton::~EnterMainButton(){}

    void GoBack::OnClick(int x,int y,unsigned char key){g->Back();}
    void GoBack::OnDoubleClick(int x,int y,unsigned char key){g->Back();}
    GoBack::GoBack(SDL_Point p,GameScene* g,const char* text,SDL_Color text_color):
    TextButton((Window*)g->window(),p,text,text_color),g(g){}
    GoBack::~GoBack(){}

    void MusicBar::OnChanged(double value){g->SetMusicVolume(value);}
    MusicBar::MusicBar(SDL_Rect r,GameScene* g,SDL_Texture* fg,SDL_Texture* bg):
    TextureBar((Window*)g->window(),r,fg,bg),g(g){}
    MusicBar::~MusicBar(){}
    void EffectBar::OnChanged(double value){g->SetEffectVolume(value);}
    EffectBar::EffectBar(SDL_Rect r,GameScene* g,SDL_Texture* fg,SDL_Texture* bg):
    TextureBar((Window*)g->window(),r,fg,bg),g(g){}
    EffectBar::~EffectBar(){}

    void ChooseButton::_release(int x,int y,int clicks,unsigned char key){
        logic(g);
        g->EndChoose();
    }
    ChooseButton::ChooseButton(SDL_Texture* b,GameScene* g,const vector<TextMod>& text,Logic func)
    :Control((Window*)g->window()),g(g){
        back=b;
        logic=func;
        _t=BuildText(text,default_font->_font);
        //按0 0计算好
        _area.w=800,_area.h=50,_area.x=240;
        SDL_QueryTexture(_t,0,0,&_rect.w,&_rect.h);
    }
    ChooseButton::~ChooseButton(){SDL_DestroyTexture(_t);}
    void ChooseButton::_draw(){
        auto r=_belong->renderer;
        r->DrawTexture(0,&_area,back);
        r->DrawTexture(0,&_rect,_t);
    }

    void SaveItem::_click(BaseListView* b,int x,int y,unsigned char key){
        game->SetSaveInput(save->name);
    }
    void SaveItem::_double_click(BaseListView* b,int x,int y,unsigned char key){
        _click(b,x,y,key);
    }
    void SaveItem::Update(SaveObject* s){
        s->item=this;
        save=s;
        auto r=game->window()->renderer;
        auto cache=r->GetTarget();
        r->SetTarget(t);
        auto state=s->state;
        for(auto& n:state->back){
            if(!n.visible||!n.a)continue;
            static SDL_Rect rect{0,0,1280,720};
            auto u=game->QueryRes("back");
            auto f=u->res_map.find(n.name);
            Uint8 a;
            auto _t=u->res[f->second].src;
            SDL_GetTextureAlphaMod(_t,&a);
            SDL_SetTextureAlphaMod(_t,n.a);
            r->DrawTexture(0,&rect,_t);
            SDL_SetTextureAlphaMod(_t,a);
        }
        for(auto& n:state->character){
            auto u=game->QueryRes(n.name);
            for(auto& m:n.ch){
                if(!m.visible||!m.a)continue;
                auto f=u->res_map.find(m.name);
                Uint8 a;
                auto _t=u->res[f->second].src;
                SDL_GetTextureAlphaMod(_t,&a);
                SDL_SetTextureAlphaMod(_t,m.a);
                r->DrawTexture(0,&n.rect,_t);
                SDL_SetTextureAlphaMod(_t,a);
            }
        }
        r->SetTarget(cache);
        name=r->RenderText(default_font,s->name,Color::Black);
        time=r->RenderText(default_font,s->time_s,Color::Black);
    }
    SaveItem::SaveItem(GameScene* g,SaveObject* s){
        game=g;
        auto r=g->window()->renderer;
        t=r->CreateTexture(1280,720);
        SDL_SetTextureBlendMode(t,SDL_BLENDMODE_BLEND);
        Update(s);
    }
    SaveItem::~SaveItem(){
        SDL_DestroyTexture(t);
        SDL_DestroyTexture(name);
        SDL_DestroyTexture(time);
    }
    void SaveItem::Draw(Renderer* render,ListState state,SDL_Rect& rect){
        SDL_Rect r=rect;
        auto w=r.w;
        auto fs=default_font->height();
        r.h-=fs<<1;
        render->DrawTexture(0,&r,t);
        r.y+=r.h;
        SDL_QueryTexture(name,0,0,&r.w,&r.h);
        r.x+=(w-r.w)>>1;
        render->DrawTexture(0,&r,name);
        r.x-=(w-r.w)>>1;
        r.y+=fs;
        SDL_QueryTexture(time,0,0,&r.w,&r.h);
        r.x+=(w-r.w)>>1;
        render->DrawTexture(0,&r,time);
    }

    void CGItem::Draw(Renderer* render,ListState state,SDL_Rect& rect){
        if(this->state->unlock){
            Uint8 a;
            auto t=this->state->t;
            SDL_GetTextureAlphaMod(t,&a);
            SDL_SetTextureAlphaMod(t,255);
            render->DrawTexture(0,&rect,t);
            SDL_SetTextureAlphaMod(t,a);
            return;
        }
    }
    CGItem::~CGItem(){}
    CGItem::CGItem(GameScene* game,CGPack* s):state(s),g(game){}
    void CGItem::_click(BaseListView* list,int x,int y,unsigned char key){
        //点击时全图展示，再点返回列表
        if(state->unlock){
            g->ShowCG(state->t);
            list->_belong->CancelFocus(list);
        }
    }
    void CGItem::_double_click(BaseListView* list,int x,int y,unsigned char key){
        _click(list,x,y,key);
    }

    CGImage::CGImage(Window* w):Image(w,1280,720){
        handle=false;
        SetEnable(false);
        SetVisible(false);
        _area.x=0,_area.y=0;
        layer=1;
    }
    void CGImage::_release(int x,int y,int clicks,unsigned char key){
        SetVisible(false);
        SetEnable(false);
    }
    void CGImage::Show(SDL_Texture* t){
        cg=t;
    }
    void CGImage::_draw(){
        if(handle){
            _belong->renderer->DrawTexture(NULL,&_area,cg);
            return;
        }
        Uint8 cache;
        SDL_GetTextureAlphaMod(cg,&cache);
        SDL_SetTextureAlphaMod(cg,255);
        _belong->renderer->DrawTexture(NULL,&_area,cg);
        SDL_SetTextureAlphaMod(cg,cache);
    }
    void LanguageSelect::OnSelect(){
        if(_select==-1)return;
        g->SetLanguage(_items->operator[](_select)->c_str());
    }
    LanguageSelect::~LanguageSelect(){}
    LanguageSelect::LanguageSelect(GameScene* g,SDL_Rect& rect,initializer_list<string*> init,
    int item_height,size_t max_item):DropList((Window*)g->window(),rect,init,item_height,max_item),g(g){}
    CGList::CGList(Window* window,SDL_Rect& rect,int spacex,int spacey,int item_w,int item_h,
    SDL_Color background,SDL_Color select_color,SDL_Color on_color,
    SDL_Color normal_scroll_color,SDL_Color on_scroll_color):
    TableView(window,rect,spacex,spacey,item_w,item_h,background,select_color,on_color,normal_scroll_color,on_scroll_color){}
    void CGList::_draw_edge(){}

    MusicItem::MusicItem(GameScene* g,const char* music,Font* f):TextItem((Window*)g->window(),music,f),game(g){}
    void MusicItem::_click(BaseListView* list,int x,int y,unsigned char key){
        if(!game->IsGaming())game->PlayMusic(_text);
    }
    void MusicItem::_double_click(BaseListView* list,int x,int y,unsigned char key){
        _click(list,x,y,key);
    }
    MusicItem::~MusicItem(){}
}